package com.chuangke.admin.service.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.chuangke.admin.constant.SysConstant;
import com.chuangke.admin.dao.SysRoleDeptDaoService;
import com.chuangke.admin.entity.SysRole;
import com.chuangke.admin.entity.SysRoleDept;
import com.chuangke.admin.entity.SysUser;
import com.chuangke.admin.entity.SysUserAuditDept;
import com.chuangke.admin.entity.SysUserDataDept;
import com.chuangke.admin.entity.SysUserRole;
import com.chuangke.admin.service.SysDeptService;
import com.chuangke.admin.service.SysRoleDeptService;
import com.chuangke.admin.service.SysRoleService;
import com.chuangke.admin.service.SysUserAuditDeptService;
import com.chuangke.admin.service.SysUserDataDeptService;
import com.chuangke.admin.service.SysUserRoleQueryService;
import com.chuangke.admin.service.SysUserService;
import com.chuangke.common.idgen.IdManager;

@Service
public class SysRoleDeptServiceImpl implements SysRoleDeptService {

	public static final String INHERIT_ROLE = "1";
	
	@Autowired
	private SysRoleService sysRoleService;
	@Autowired
	private SysUserService sysUserService;
	@Autowired
	private SysDeptService sysDeptService;
	@Autowired
	private SysUserRoleQueryService sysUserRoleQueryService;
	@Autowired
	private SysUserAuditDeptService sysUserAuditDeptService;
	@Autowired
	private SysUserDataDeptService sysUserDataDeptService;
	@Autowired
	private SysRoleDeptDaoService sysRoleDeptDaoService;
	
	@Transactional
	@Override
	public void saveDataRule(String roleId, String dataRule, List<String> deptIds) {
		//更新角色数据规则
		sysRoleService.updateDataRule(roleId,dataRule);
		List<SysUser> userList= sysUserService.findUsersInheritRole(roleId);
		if(userList!=null&& !userList.isEmpty()) {
			sysUserDataDeptService.remove(new QueryWrapper<SysUserDataDept>().lambda().in(SysUserDataDept::getUserId,userList.stream().map(SysUser::getId).collect(Collectors.toList())));
		}
		if(SysConstant.RULE_CUSTOM_DEPT.equals(dataRule)) {//如果是自选部门，保存数据到sysRoleDept
			this.saveRoleDept(roleId,SysConstant.RULE_TYPE_DATA,deptIds);
			addCustomUserDataRule(userList,deptIds);
		}else {
			addOtherUserDataRule(userList,dataRule);
		}
		
	}
	

	/**
	 * 添加用户的数据权限（只更新继承角色的用户）(自选部门)
	 * @param deptIds
	 */
	private void addCustomUserDataRule(List<SysUser> userList, List<String> deptIds) {
		List<SysUserDataDept> list= new ArrayList<>();
		for(String deptId:deptIds) {
			for(SysUser user :userList) {
				SysUserDataDept userDataDept=new SysUserDataDept();
				userDataDept.setId(IdManager.nextId());
				userDataDept.setDeptId(deptId);
				userDataDept.setUserId(user.getId());
				list.add(userDataDept);
			}
		}
		sysUserDataDeptService.saveBatchDataRule(list);
	}
	
	/**
	 * 添加用户的数据权限（只更新继承角色的用户）(其他部门)
     */
	private void addOtherUserDataRule(List<SysUser> userList, String dataRule) {
		List<SysUserDataDept> list= new ArrayList<>();
		for(SysUser user :userList) {
			List<String> deptIds=sysDeptService.findDeptByRule(user.getDeptId(),dataRule);
			for(String deptId:deptIds) {
				SysUserDataDept userDataDept=new SysUserDataDept();
				userDataDept.setId(IdManager.nextId());
				userDataDept.setDeptId(deptId);
				userDataDept.setUserId(user.getId());
				list.add(userDataDept);
			}
		}
		sysUserDataDeptService.saveBatchDataRule(list);
	}

	@Transactional
	@Override
	public void saveAuditRule(String roleId, String auditRule, List<String> deptIds) {
		//更新角色审批规则
		sysRoleService.updateAuditRule(roleId,auditRule);
		List<SysUser> userList= sysUserService.findUsersInheritRole(roleId);
		if(userList!=null&& !userList.isEmpty()) {
			sysUserAuditDeptService.remove(new QueryWrapper<SysUserAuditDept>().lambda().in(SysUserAuditDept::getUserId,userList.stream().map(SysUser::getId).collect(Collectors.toList())));
		}
		if(SysConstant.RULE_CUSTOM_DEPT.equals(auditRule)) {
			this.saveRoleDept(roleId,SysConstant.RULE_TYPE_AUDIT,deptIds);
			addCustomUserAuditRule(roleId,userList,deptIds);
		}else {
			addOtherUserAuditRule(roleId,userList,auditRule);
		}
		
	}
	
	/**
	 * 添加用户的审批权限（只更新继承角色的用户）(其他部门)
     */
	private void addOtherUserAuditRule(String roleId,List<SysUser> userList, String auditRule) {
		List<SysUserAuditDept> list= new ArrayList<>();
		for(SysUser user :userList) {
			List<String> deptIds=sysDeptService.findDeptByRule(user.getDeptId(),auditRule);
			for(String deptId:deptIds) {
				SysUserAuditDept userAuditDept=new SysUserAuditDept();
				userAuditDept.setId(IdManager.nextId());
				userAuditDept.setDeptId(deptId);
				userAuditDept.setUserId(user.getId());
				userAuditDept.setRoleId(roleId);
				list.add(userAuditDept);
			}
		}
		sysUserAuditDeptService.saveBatchAuditRule(list);
	}
	
	/**
	 * 添加用户的审批权限（只更新继承角色的用户）(自选部门)
	 * @param roleId
	 * @param deptIds
	 */
	private void addCustomUserAuditRule(String roleId,List<SysUser> userList, List<String> deptIds) {
		List<SysUserAuditDept> list= new ArrayList<>();
		for(String deptId:deptIds) {
			for(SysUser user :userList) {
				SysUserAuditDept userAuditDept=new SysUserAuditDept();
				userAuditDept.setId(IdManager.nextId());
				userAuditDept.setDeptId(deptId);
				userAuditDept.setUserId(user.getId());
				userAuditDept.setRoleId(roleId);
				list.add(userAuditDept);
			}
		}
		sysUserAuditDeptService.saveBatchAuditRule(list);
	}

	public void saveRoleDept(String roleId, String rule, List<String> deptIds) {
		List<SysRoleDept> list= new ArrayList<>();
		List<SysRoleDept> dataList=sysRoleDeptDaoService.list() ;
		for(String deptId:deptIds) {
			SysRoleDept roleDept=new SysRoleDept();
			roleDept.setDeptId(deptId);
			roleDept.setRoleId(roleId);
			roleDept.setType(rule);
			List<SysRoleDept> filterList=dataList.stream().filter(item->Objects.equals(item.getDeptId(), deptId)&&Objects.equals(item.getRoleId(), roleId)&&Objects.equals(item.getType(), rule)).collect(Collectors.toList());
			if(filterList==null|| filterList.isEmpty()) {
				roleDept.setId(IdManager.nextId());
				list.add(roleDept);
			}
		}
		sysRoleDeptDaoService.saveBatch(list);
		
	}

	@Transactional
	@Override
	public void synUserInheritRole(String userId) {
		SysUser sysUser=sysUserService.findById(userId);
		List<SysUserRole> userRoleList= sysUserRoleQueryService.findByUserId(userId);
		List<SysRole> roleList=sysRoleService.findRoles(userRoleList.stream().map(SysUserRole::getRoleId).collect(Collectors.toList()));
		sysUserDataDeptService.remove(new QueryWrapper<SysUserDataDept>().lambda().eq(SysUserDataDept::getUserId,userId));
		sysUserAuditDeptService.remove(userId, roleList.stream().map(SysRole::getId).collect(Collectors.toList()));
		roleList.forEach(role->{
			List<SysRoleDept> roleDeptList=sysRoleDeptDaoService.list(new QueryWrapper<SysRoleDept>().lambda().eq(SysRoleDept::getRoleId, role.getId()));
			List<String> deptIdList=roleDeptList.stream().map(SysRoleDept::getDeptId).collect(Collectors.toList());
			//同步数据权限
			String dataRule=role.getDataRule();
			if(SysConstant.RULE_CUSTOM_DEPT.equals(dataRule)) {
				addCustomUserDataRule(Collections.singletonList(sysUser),deptIdList);
			}else {
				addOtherUserDataRule(Collections.singletonList(sysUser),dataRule);
			}
			//同步审批权限
			String auditRule=role.getAuditRule();
			if(SysConstant.RULE_CUSTOM_DEPT.equals(auditRule)) {
				addCustomUserAuditRule(role.getId(), Collections.singletonList(sysUser),deptIdList);
			}else {
				addOtherUserAuditRule(role.getId(), Collections.singletonList(sysUser),dataRule);
			}
		});
		//更新用户是否继承角色权限
		sysUserService.changeInheritRole(userId,INHERIT_ROLE);
	}


	@Transactional
	@Override
	public void removeAuditRule(String roleId) {
		List<SysUser> userList= sysUserService.findUsersInheritRole(roleId);
		List<String> ids=userList.stream().map(SysUser::getId).collect(Collectors.toList());
		if(!ids.isEmpty()) {
			sysRoleDeptDaoService.remove(new QueryWrapper<SysRoleDept>().lambda().eq(SysRoleDept::getRoleId, roleId));
			sysUserAuditDeptService.removeAuditRule(new QueryWrapper<SysUserAuditDept>().lambda().eq(SysUserAuditDept::getRoleId,roleId).in(SysUserAuditDept::getUserId, ids));
		}
	}


	@Transactional
	@Override
	public void removeDataRule(String roleId) {
		List<SysUser> userList= sysUserService.findUsersInheritRole(roleId);
		List<String> ids=userList.stream().map(SysUser::getId).collect(Collectors.toList());
		if(!ids.isEmpty()) {
			sysRoleDeptDaoService.remove(new QueryWrapper<SysRoleDept>().lambda().eq(SysRoleDept::getRoleId, roleId));
			sysUserDataDeptService.removeDataRule(new QueryWrapper<SysUserDataDept>().lambda().in(SysUserDataDept::getUserId, ids));
		}
	}

}
